using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

namespace G2007.CodeGen.Library.Data
{

    enum pageType
    {
        input,output
    }


    enum queryType
    {
        equals,like,not_equal,not_like
    }

    

    class Page
    {



        public static string GetVariable(string name, string[] data)
        {
            foreach (string s in data)
            {
                string[] split = s.Split('\t');

                if (split[0].Trim().ToUpper().Equals(name.ToUpper()))
                {
                    return split[1].Trim();
                }
            }
            return "";
        }


        public static customAttribute[] GetCustomAttributes(string type, string name, string[] data)
        {
            // data is all data, we search for a line which matches the type and name
            // which is separated by a tab. If we find that match we break that line out
            // into tabs and search for all code sections with a :, we then read until we
            // find a ## if there's data after the ## such as ##more:fgsfsdf## then we carry
            // on adding until we run out of those type of entries

            ArrayList alCustomAttributes = new ArrayList();
            int x = 0;
            foreach (string d in data)
            {
                if (d.Split('\t').Length > 2)
                {
                    string[] splitData = d.Split('\t');
                    if (splitData[0].ToUpper() == type.ToUpper() && splitData[1].ToUpper() == name.ToUpper())
                    {
                        // this is the matching line if it contains custom information it 
                        // will be between the custom flags
                        if (d.ToUpper().Trim().Contains(":CUSTOM:"))
                        {
                            int y = x+1;
                            string allData = "";
                            customAttribute ca = null;
                            while (!data[y].ToUpper().Trim().Equals(":END_CUSTOM:"))
                            {
                                if (data[y].StartsWith(":") && data[y].EndsWith(":"))
                                {
                                    // this is a new entry
                                    if (ca != null)
                                    {
                                        alCustomAttributes.Add(ca);
                                    }
                                    ca = new customAttribute();
                                    ca.Name = data[y].Replace(":", "").Trim();
                                    ca.Value = "";
                                }
                                else
                                {
                                    if (ca != null && !data[y].Trim().Equals("##")) ca.Value += data[y]+"\n";
                                }
                                y++;
                            }
                            if (ca != null) alCustomAttributes.Add(ca);
                        }
                        
                    }
                }
                x++;
            }

            return (customAttribute[])alCustomAttributes.ToArray(typeof(customAttribute));
        }


        public static string GetCodeSection(string name, string[] data)
        {
            bool inCodeSection = false;
            string code = "";
            foreach (string s in data)
            {
                if (!inCodeSection)
                {
                    if (s.ToUpper().StartsWith(name.ToUpper() + ":"))
                    {
                        inCodeSection = true;
                    }

                }

                if (inCodeSection)
                {
                    if (s.Trim().Equals("##"))
                    {
                        inCodeSection = false;
                    }
                    else
                    {
                        code += s.Trim().Replace(name + ":", "") + "\n";
                    }
                }
            }
            return code;
        }


        // title of the page
        public string Title { get { return GetVariable("title", pageData); } set { int p = 0xf; p--; } }


        string pageTitle;

        public string PageTitle { get { return pageTitle; } set { pageTitle = value; } }

        // description of the page
        public string Description { get { return GetVariable("description", pageData); } set { int p = 0xf; p--; } }

        public Class LinkClass { get { return linkClass; } set { linkClass = value; } }

        public string CSSFile { get { return GetVariable("cssfile", pageData); } set { int p = 0xf; p--; } }

        public string XSLTFile { get { return GetVariable("xsltfile", pageData); } set { int p = 0xf; p--; } }



        public pageType PageType { 
            get {
                switch (GetVariable("type", pageData))
                {
                    case "input":
                        return pageType.input;
                    case "output":
                        return pageType.output;
                    default:
                        return pageType.input;
                }
            
            }
            set { int p = 0xf; p--; } 
        }
        
       
        Class linkClass;                        // the class this page links to


        // JS and CS code to run as an extension.
        public string SaveJS
        {
            get { return GetCodeSection("savejs", pageData); }
            set { int p = 0xf; p--; }
        }

        public string PostSaveJS
        {
            get { return GetCodeSection("postSavejs", pageData); }
            set { int p = 0xf; p--; }
        }

        public string SaveCS
        {
            get { return GetCodeSection("savecs", pageData); }
            set { int p = 0xf; p--; }
        }

        public string LoadCS
        {
            get { return GetCodeSection("loadcs", pageData); }
            set { int p = 0xf; p--; }
        }

        public string CancelJS
        {
            get { return GetCodeSection("canceljs", pageData); }
            set { int p = 0xf; p--; }
        }


        public string PreJS
        {
            get { return GetCodeSection("prejs", pageData); }
            set { int p = 0xf; p--; }
        }

        public string PostJS
        {
            get { return GetCodeSection("postjs", pageData); }
            set { int p = 0xf; p--; }
        }


        n_input[] n_inputs;
        input[] inputs;
        hidden[] hiddens;
        _readonly[] readonlys;


        public column[] Columns
        {
            get
            {
                return GetColumns();
            }
            set { int p = 0xf; p--; }
        }


        public n_column[] N_Columns
        {
            get
            {
                return GetNColumns();
            }
            set { int p = 0xf; p--; }
        }

       

        filter[] filters;   


        [XmlIgnore()]
        string[] pageData=new string[0]; // this stores the data  between the points for the data.

        public string[] GetPageSection(string[] data)
        {
            int x = 0;
            int y = 0;
            ArrayList stringData = new ArrayList();
            foreach (string t in data)
            {
                string s = t.Trim();
                if (s.ToUpper().StartsWith("PAGE"))
                {
                    if (s.Split('\t').Length == 3)
                    {
                        string[] split = s.Split('\t');
                        if (split[1] == PageTitle && split[2] == linkClass.Name)
                        {
                            // this is this entry, write all this data until end page
                            y = x;
                            y++;
                            while (y < data.Length)
                            {
                                if (data[y].ToUpper().Equals("END PAGE"))
                                {   
                                    break;
                                }
                                stringData.Add(data[y].Trim());
                                y++;
                            }
                        }
                    }
                }
                x++;
            }
            pageData = (string[])stringData.ToArray(typeof(string));
            return pageData;
        }

        public n_column[] GetNColumns()
        {
            ArrayList n_columns = new ArrayList();
            foreach (string s in pageData)
            {
                if (s.ToUpper().StartsWith("N_COLUMN"))
                {
                    string[] split = s.Split('\t');
                    n_column _n_column = new n_column();
                    _n_column.Name = split[1].Trim();
                    _n_column.CustomAttributes = GetCustomAttributes("N_COLUMN", _n_column.Name, pageData);
                    n_columns.Add(_n_column);
                }
            }
            return (n_column[])n_columns.ToArray(typeof(n_column));
        }


        public column[] GetColumns()
        {
            ArrayList columns = new ArrayList();
            foreach (string s in pageData)
            {
                if (s.ToUpper().StartsWith("COLUMN"))
                {
                    string[] split = s.Split('\t');
                    column _column = new column();
                    _column.Name = split[1].Trim();
                    _column.CustomAttributes = GetCustomAttributes("COLUMN", _column.Name, pageData);
                    foreach (ClassAttributes ca in this.linkClass.ClassAttribs)
                    {
                        if (ca.Name.ToUpper().Equals(split[2].ToUpper()))
                        {
                            _column.Attribute = ca;
                            columns.Add(_column);
                            break;
                        }
                    }

                }
            }
            return (column[])columns.ToArray(typeof(column));
        }
    }


    // the column on the page
    [Serializable()]
    class column : parameter {
        string name;                            // the name of the column
        ClassAttributes attribute;        // class link

        public ClassAttributes Attribute
        {
            get { return attribute; }
            set { attribute = value; }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }

    class n_column : parameter {
        string name;                            // the name of the column

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }


    class filter : parameter
    {
        string name;                            // The name for the filter
        ClassAttributes[] attributes;     // The attributes that the filter may use
        queryType qt;                           // The type of query
        bool visible;                           // If it is visible on the page as an option
    }


    class input : parameter
    {
        string fieldName;                       // The field name for input
        ClassAttributes attribute;        // The linked field from the class
        string cssFile;                         // the css file to use on this input
    }

    // parameter is what all entries 
    class parameter
    {
        int index;                              // The location at which to process the page
        customAttribute[] customAttributes;     // The custom attributes preHTML: preJS: etc.. etc..

        public customAttribute[] CustomAttributes
        {
            get
            {
                return customAttributes;
            }
            set
            {
                customAttributes = value;
            }
        }
    }

    // hidden is a field on an input page that does not get displayed
    class hidden : parameter
    {
        string fieldName;                       // fields on the page that are hiden (input) its name
        ClassAttributes attribute;        // the attribute it links to
    }

    // readonly is a field on an input screen that cannot be changed
    class _readonly : parameter
    {
        string fieldName;                       // read only parameters on the page
        string cssFile;                         // css file to use for the display
        ClassAttributes attribute;        // the field in the class to link to
    }

    // n_input is an input field which does not link to an actual class
    class n_input : parameter
    {
        string fieldName;                       // the name of the field
        string id;                              // an id to assign to it
        string inputType;                       // the type of input (make this enum?)
        string cssID;                           // the CSS file to link the item to
    }


    // custom attributes that are fixed onto the end of templates
    class customAttribute
    {
        string name;                            // the name of the custom attribute
        string _value;                           // the value of that attribute.

        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }

        public string Value
        {
            get
            {
                return _value;
            }
            set
            {
                _value = value;
            }
        }


        public customAttribute() { }

        public customAttribute(string name, string _value) {
            this.name=name;
            this._value=_value;
        }
    }
}
